package com.ee.chat.api.service.impl;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ee.chat.api.common.CommonService;
import com.ee.chat.api.service.IDynamicService;
import com.ee.chat.common.bean.Result;
import com.ee.chat.common.dao.*;
import com.ee.chat.common.entity.*;
import com.ee.chat.common.serconfig.MyMapConfig;
import com.ee.chat.common.service.IYieldService;
import com.ee.chat.common.util.ConstantsUtil;
import com.ndhutu.ee.util.StringUtil;
import com.ndhutu.ee.util.map.baidu.MapUtil;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.TimeUnit;

@Service
public class DynamicServiceImpl implements IDynamicService {
    @Resource(name = "stringRedisTemplate")
    StringRedisTemplate redisTemplate;
    @Resource
    UserDynamicMapper userDynamicMapper;
    @Resource
    HostDynamicConfigMapper hostDynamicConfigMapper;
    @Resource
    HostMapper hostMapper;
    @Resource
    UserDynamicWatchLogMapper userDynamicWatchLogMapper;
    @Resource
    UserDynamicLikeLogMapper userDynamicLikeLogMapper;
    @Resource
    UserVipMapper userVipMapper;
    @Resource
    UserDynamicBuyLogMapper userDynamicBuyLogMapper;
    @Resource
    UserWalletMapper userWalletMapper;

    @Resource
    CommonService commonService;
    @Resource
    IYieldService yieldService;

    @Resource
    MyMapConfig mapConfig;


    @Override
    public void handleDynamic(List<Map<String, Object>> dynamics) {
        Iterator<Map<String, Object>> it = dynamics.iterator();
        while (it.hasNext()){
            Map<String, Object> dynamic = it.next();
            List<String> url = JSONArray.parseArray(dynamic.get("url")+"", String.class);
//            List<Map<String, Object>> likeLogs = userDynamicLikeLogMapper.getNewestLikeLogs(Integer.parseInt(dynamic.get("id")+""));
            String lnglat = null;
            if(dynamic.get("lnglat") != null){
                lnglat = dynamic.get("lnglat")+"";
                lnglat = lnglat.replace("POINT(", "").replace(")", "").replace(" ", ",");
            }

            dynamic.put("url", url);
//            dynamic.put("likeLogs", likeLogs);
            dynamic.put("lnglat", lnglat);
        }
    }

    @Override
    public Result getDynamics(String token, Integer type, Integer id, String location, Integer page, Integer limit) throws Exception {
        Map<String, Object> data = new HashMap<>();

        Integer userId = commonService.getUserId(token);
        List<Map<String, Object>> dynamics;

        Page<Map<String, Object>> p = new Page<>(page, limit);
        IPage<Map<String, Object>> iPage;

        if(type == 0){  //热门
            String key = ConstantsUtil.DYNAMIC_HISTORY_HOT + userId;
            Set<String> historyIds = new HashSet<>();
            if(page == 1){
                //重置浏览记录
                redisTemplate.expire(key+":browseLog", -1, TimeUnit.MINUTES);

            }else {
                historyIds.addAll(redisTemplate.opsForSet().members(key));
            }

            iPage = userDynamicMapper.getDynamicsOrderByWI(p, userId, historyIds);

        }else if(type == 1){  //最新
            iPage = userDynamicMapper.getDynamicOrderByTime(p, id, userId);

        }else if(type == 2){    //附近
            if(StringUtil.isEmpty(location)){
                return Result.returnFailure("location不能为空");
            }

            Double lng = Double.parseDouble(location.split(",")[0]);
            Double lat = Double.parseDouble(location.split(",")[1]);
            iPage = userDynamicMapper.getDynamicOrderDistance(p, userId, lng, lat);

        }else if(type == 3){    //私密视频
            iPage = userDynamicMapper.getDynamicOrderType(p, userId, 1);

        }else if(type == 4){    //私密图片
            iPage = userDynamicMapper.getDynamicOrderType(p, userId, 0);
        }else{
            return Result.returnFailure("type错误");
        }

        dynamics = iPage.getRecords();
        handleDynamic(dynamics);

        data.put("dynamics", dynamics);
        data.put("id", page == 1 ? (dynamics.size() == 0 ? 0 : dynamics.get(0).get("id")) : id);

        return Result.returnSuccess(data);
    }

    @Override
    public Result likeDynamic(String token, Integer id, Integer like) throws Exception {
        Integer userId = commonService.getUserId(token);

        QueryWrapper<UserDynamicLikeLog> wrapper = new QueryWrapper<>();
        wrapper.eq("dynamic_id", id);
        wrapper.eq("like_user_id", userId);
        if(like == 0){
            userDynamicLikeLogMapper.delete(wrapper);
        }else{
            UserDynamicLikeLog userDynamicLikeLog = userDynamicLikeLogMapper.selectOne(wrapper);
            if(userDynamicLikeLog == null){
                userDynamicLikeLog = new UserDynamicLikeLog(id, userDynamicMapper.selectById(id).getUserId(), userId);
                userDynamicLikeLogMapper.insert(userDynamicLikeLog);
            }
        }

        return Result.returnSuccess(null);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result buyDynamic(String token, Integer id) throws Exception {
        Map<String, Object> data = new HashMap<>();

        Integer userId = commonService.getUserId(token);

        UserDynamic dynamic = userDynamicMapper.selectById(id);
        if(dynamic.getConfigId() <= 0){
            return Result.returnFailure( "免费动态无需购买");
        }
        if(dynamic.getUserId() == userId){
            return Result.returnFailure("自己动态无需购买");
        }
        UserVip userVip = userVipMapper.selectValidVip(userId);
        if(userVip != null){
            return Result.returnFailure("会员无需购买");
        }

        UserDynamicBuyLog dynamicBuyLog = userDynamicBuyLogMapper.getUserBuyLog(userId, id);
        if(dynamicBuyLog != null){
            return Result.returnFailure("已购买过该动态，无需重复购买");
        }
        HostDynamicConfig dynamicConfig = hostDynamicConfigMapper.selectById(dynamic.getConfigId());

        /*
         * 购买动态
         * 1. 用户金币扣除
         *    添加扣除记录、动态购买记录、消费记录，更新钱包
         * 2. 主播积分增加
         *     添加积分记录，更新钱包
         */
        UserWallet wallet = userWalletMapper.getByUserId(userId);
        //PP
        int coin = dynamicConfig.getCoin();
        //积分
        double credit = dynamicConfig.getEarn();
        if(wallet == null || wallet.getActiveCoin() < coin){
            return Result.returnFailure("金币不足，无法观看");
        }

        //1.
        dynamicBuyLog = new UserDynamicBuyLog(dynamic.getUserId(), userId, id, coin, credit);
        userDynamicBuyLogMapper.insert(dynamicBuyLog);

        //消费
        yieldService.consume(userId, 1, dynamic.getUserId(), dynamicBuyLog.getId()+"", coin, credit);

        //清除app端图片缓存
        /*if(dynamic.getType() == 0){ //图片
            List<String> urls = JSONArray.parseArray(dynamic.getUrl(), String.class);
            List<String> news = new ArrayList<>();
            for(String url : urls){
                if(url.indexOf("modify=") < 0){
                    url += "&modify=0";
                }else{
                    int modify = Integer.parseInt(url.substring(url.indexOf("modify=") + 7)) + 1;
                    url = url.substring(0, url.indexOf("modify=") + 7) + modify;
                }
                news.add(url);
            }
            dynamic.setUrl(JSONObject.toJSONString(news));
        }else if(dynamic.getType() == 1){   //视频
            String cover = dynamic.getCover();
            int modify = Integer.parseInt(cover.substring(cover.indexOf("modify=") + 7)) + 1;
            cover = cover.substring(0, cover.indexOf("modify=")) + "modify=" + modify;
            dynamic.setCover(cover);
        }*/
        userDynamicMapper.updateById(dynamic);

        data.put("url", dynamic.getUrl());
        return Result.returnSuccess(data);
    }

    /**
     * 获取动态价格列表
     * @Author Shane
     * @Date 2019/10/8 18:37
     * @param
     * @return
     */
    @Override
    public Result getDynamicCharge(String token, Integer type) throws Exception {
        Map<String, Object> data = new HashMap<>();
        Integer userId = commonService.getUserId(token);
        Host host = hostMapper.selectByUserId(userId);
        Object charges = null;
        if(host != null){
            if(type == null){
                List<Map<String, Object>> picCharges = hostDynamicConfigMapper.getDynamicCharge(0);
                List<Map<String, Object>> videoCharges = hostDynamicConfigMapper.getDynamicCharge(1);
                charges = new HashMap<>();
                ((HashMap) charges).put("picCharges", picCharges);
                ((HashMap) charges).put("videoCharges", videoCharges);
            }else{
                charges = hostDynamicConfigMapper.getDynamicCharge(type);
            }
            data.put("charges", charges);
        }else{
            data.put("charges", new ArrayList<>());
        }

        return Result.returnSuccess(data);
    }

    /**
     * 发布动态
     * @Author Shane
     * @Date 2019/10/8 18:46
     * @param
     * @return
     */
    @Override
    public Result publishDynamic(String token, String title, String dynamic, Integer type, Integer chargeId, String address, String location) throws Exception {
        Map<String, Object> data = new HashMap<>();
        Integer userId = commonService.getUserId(token);

        //检验标题中是否包含链接
        if(StringUtil.checkLink(title)){
            return Result.returnFailure("标题中包含外部链接");
        }

        String cover = null;
        List<String> urls = JSONArray.parseArray(dynamic, String.class);
        if(type == 0){
            List<String> news = new ArrayList<>();
            for(String url : urls){
                news.add(url);
            }
            dynamic = JSONObject.toJSONString(news);
        }else if(type == 1){
            cover = urls.get(0) + "?x-oss-process=video/snapshot,t_1,f_png,w_0,h_0,ar_auto";
        }
        Host host = hostMapper.selectByUserId(userId);
        if(host == null){
            chargeId = 0;
        }
        UserDynamic userDynamic = new UserDynamic(userId, type, cover, dynamic, title, chargeId, address, location);
        userDynamicMapper.insertDynamic(userDynamic);

        return Result.returnSuccess(data);
    }

    @Override
    public Result updDynamicCharge(String token, Integer id, Integer chargeId) throws Exception {
        Integer userId = commonService.getUserId(token);

        Host host = hostMapper.selectByUserId(userId);
        if(host == null){
            return Result.returnFailure("普通用户不能修改动态价格");
        }

        UserDynamic userDynamic = userDynamicMapper.selectById(id);
        if(!userDynamic.getUserId().equals(userId)){
            return Result.returnFailure("不能修改他人动态");
        }

        UserDynamic temp = new UserDynamic();
        temp.setId(userDynamic.getId());
        temp.setConfigId(chargeId);
        userDynamicMapper.updateById(temp);

        return Result.returnSuccess(null);
    }

    @Override
    public Result delDynamic(String token, Integer id) throws Exception {
        Integer userId = commonService.getUserId(token);

        UserDynamic userDynamic = userDynamicMapper.selectById(id);
        if(!userDynamic.getUserId().equals(userId)){
            return Result.returnFailure("不能删除他人动态");
        }

        UserDynamic temp = new UserDynamic();
        temp.setId(userDynamic.getId());
        temp.setStatus(1);
        userDynamicMapper.updateById(temp);

        return Result.returnSuccess(null);
    }

    @Override
    public Result addWatchLog(String token, Integer id) throws Exception {
        Integer userId = commonService.getUserId(token);

        UserDynamicWatchLog userDynamicWatchLog = new UserDynamicWatchLog(id, userId);
        userDynamicWatchLogMapper.insert(userDynamicWatchLog);

        return Result.returnSuccess(null);
    }

    @Override
    public Result adderSuggestion(String token, String city, String location, String search) throws Exception {
        Map<String, Object> data = new HashMap<>();

        List<Map<String, Object>> addrs = MapUtil.suggestion(city, location, search, mapConfig);
        Iterator<Map<String, Object>> it = addrs.iterator();
        while (it.hasNext()){
            Map<String, Object> addr = it.next();
            if(StrUtil.isEmptyIfStr(addr.get("location")) || StrUtil.isEmptyIfStr(addr.get("uid"))){
                it.remove();
            }
        }

        data.put("addrs", addrs);

        return Result.returnSuccess(data);
    }
}
